package com.cardmanager.pro.scanner;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.management.StringValueExp;
import javax.servlet.http.HttpServletRequest;

import cn.jh.common.exception.ServiceException;
import cn.jh.common.pay.client.FreeQuickClient;
import cn.jh.common.pay.client.FreeQuickRequest;
import cn.jh.common.pay.client.FreeQuickResponse;
import cn.jh.common.pay.enumtype.EncryptTypeEnum;
import cn.jh.common.pay.utils.StringUtils;
import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.CommonsUtil;
import com.alibaba.fastjson.JSON;
import com.cardmanager.pro.business.ConsumeTaskPOJOBusiness;
import com.cardmanager.pro.executor.BaseExecutor;
import com.cardmanager.pro.pojo.ConsumeTaskPOJO;
import com.cardmanager.pro.repository.RepaymentTaskPOJORepository;
import net.sf.json.JSONObject;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cardmanager.pro.business.RepaymentTaskPOJOBusiness;
import com.cardmanager.pro.pojo.RepaymentTaskPOJO;

/**
 * 通道执行还款计划时间表
 * @author lichengying
 */
@Configuration
@Controller
@EnableScheduling
public class RepaymentTaskScanner extends ApplicationObjectSupport{

	private final Logger LOG = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private RepaymentTaskPOJOBusiness repaymentTaskPOJOBusiness;

	@Autowired
	private ConsumeTaskPOJOBusiness consumeTaskPOJOBusiness;

	@Autowired
	private RepaymentTaskPOJORepository repaymentTaskPOJORepository;

	@Autowired
	private BaseExecutor baseExecutor;
	
	@Value("${schedule-task.on-off}")
	private String scanOnOff;

	/**
	 * 计划被终止，执行；
	 * @param map
	 */
	private void failWith(Map map,RepaymentTaskPOJO pojo){
		List<RepaymentTaskPOJO> result = repaymentTaskPOJOBusiness.findTaskTypeAndTaskStatus(pojo.getUserId(),pojo.getCreditCardNumber());
		if(result.size() > 0 && result.size() < 2){
			for(RepaymentTaskPOJO resul : result){
				ConsumeTaskPOJO po = new ConsumeTaskPOJO();
				po.setOrderCode(resul.getOrderNo());
				po.setTaskStatus(0);
				po.setRealAmount(resul.getRealAmount());
				po.setAmount(resul.getAmount());
				po.setUserId(resul.getUserId());
				po.setCreditCardNumber(resul.getCreditCardNumber());
				po.setRepaymentTaskId(resul.getRepaymentTaskId());
				po.setRate(resul.getRate());
				po.setServiceCharge(resul.getServiceCharge());
				po.setTotalServiceCharge(resul.getTotalServiceCharge());
				po.setChannelId(resul.getChannelId());
				po.setChannelTag(resul.getChannelTag());
				po.setTaskType(2);
				po.setConsumeTaskId(resul.getRepaymentTaskId());
				po.setOrderStatus(1);
				po.setPlanType(resul.getPlanType());
				po.setExecuteDate(resul.getExecuteDate());
				po.setExecuteDateTime(resul.getExecuteDateTime());
				po.setDescription("还款计划失败，执行扣款异常任务");
				consumeTaskPOJOBusiness.save(po);
			}
		}

		pojo.setErrorMessage((String) map.getOrDefault("code","0"));
		pojo.setTaskStatus(2);
		pojo.setRealAmount(BigDecimal.ZERO);
		pojo.setReturnMessage((String) map.getOrDefault("msg","0"));

		//查询剩下未执行的计划，更新为还款失败；
		List<RepaymentTaskPOJO> list = repaymentTaskPOJORepository.findByOrderNo(pojo.getOrderNo());
		if(list.size() > 0){
			LOG.debug("========task-table-start=========");
			for(RepaymentTaskPOJO taskPOJO:list){
				taskPOJO.setTaskStatus(4);
			}
			repaymentTaskPOJORepository.save(list);
			LOG.debug("========task-table-end=========");
		}
	}

	@Scheduled(cron = "0 0/5 * * * ?")
	//@RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/verify/card/isuserable")
	public void synQueryTask() {
		LOG.debug("=======查询交易是否成功start=========");
		List<RepaymentTaskPOJO> list = repaymentTaskPOJORepository.findByTaskStatus(4);
		if(list.size() > 0){
			for (RepaymentTaskPOJO repaymentTaskPOJO : list) {
				Map<String,String> map = baseExecutor.querySyn(repaymentTaskPOJO.getOrderNo());
				String result = MapUtils.getString(map,"result");
				if (StringUtils.isNotBlank(result) && !result.equals("null")) {
					Map<String,String> resultMap = JSONObject.fromObject(result);
					String status = MapUtils.getString(resultMap,"payStatus");
					if (status.equals("1")) {
						repaymentTaskPOJO.setOrderStatus(1);
						repaymentTaskPOJO.setTaskStatus(1);
					} else {
						repaymentTaskPOJO.setOrderStatus(2);
						repaymentTaskPOJO.setTaskStatus(2);
					}
				}
			}

			repaymentTaskPOJORepository.save(list);
		}
		LOG.debug("=======查询交易是否成功end=========");
	}


	/**
	 * 用户做代还任务
	 * 1：每天扣款两笔，还款一笔；
	 * 2：两笔消费时间不得小于3小时，还款时间和消费时间间隔不得低于2小时
	 * 每五分钟执行一次，避免任务过多导致第一个任务未执行完，导致后续任务异常
	 */
	@Scheduled(cron = "0 0/5 * * * ?")
	public void autoScanTaskType2AndTaskStatus0RepaymentTaskPay() {
		LOG.debug("=======执行代还交易任务开始=========");
		List<RepaymentTaskPOJO> list = repaymentTaskPOJOBusiness.findTaskType2AndTaskStatus0RepaymentTaskPay();
		if(list.size() > 0){
			this.executeTask(list);
		}
		LOG.debug("=======执行代还交易任务技术=========");
	}

	@Scheduled(cron = "0 0/5 * * * ?")
	public void autoScanTaskType2AndTaskStatus0Repayment() {

		LOG.debug("=======执行代还任务开始=========");
		List<RepaymentTaskPOJO> list = repaymentTaskPOJOBusiness.findTaskType2AndTaskStatus0RepaymentTask();
		if(list.size() > 0){
			this.executeTask(list);
		}
		LOG.debug("=======执行代还任务技术=========");
	}

	/**
	 * 执行定时任务
	 */
	public void executeTask(List<RepaymentTaskPOJO> list){
		Map<String,String> map = new HashMap<>();
		for (RepaymentTaskPOJO pojo : list) {
			if(pojo.getTaskType() == 1){
				LOG.debug("========代还消费任务执行中start=========");
				map = baseExecutor.paymentConsumptionTask(String.valueOf(pojo.getAmount()),pojo.getUserId(),pojo.getCreditCardNumber(),String.valueOf(pojo.getRealAmount())
						,String.valueOf(pojo.getRate()),pojo.getChannelId(),pojo.getChannelTag(),pojo.getOrderNo());
			}else{
				LOG.debug("========代还还款任务执行start=========");
				map = baseExecutor.paymentRepaymentTask(String.valueOf(pojo.getAmount()),pojo.getUserId(),
						pojo.getCreditCardNumber(),pojo.getChannelId(),String.valueOf(pojo.getRate()),String.valueOf(pojo.getRealAmount()),pojo.getChannelTag());
			}
			String respCode = MapUtils.getString(map,"resp_code");
			if (respCode.equals(CommonConstants.SUCCESS)) {
				LOG.debug("========task-passageway-success=========");
				pojo.setReturnMessage("还款成功!");
				pojo.setTaskStatus(1);
				repaymentTaskPOJOBusiness.save(pojo);
			} else {
				LOG.debug("========task-passageway-fail=========");
				pojo.setReturnMessage("还款失败!");
				pojo.setTaskStatus(2);
				//还款失败
				this.failWith(map,pojo);
			}
		}
	}

}
